<?php
/**
 * +----------------------------------------------------------------------
 * | 九月科技-ztuc.cn
 * +----------------------------------------------------------------------
 *                      .::::.
 *                    .::::::::.            | AUTHOR: siyu
 *                    :::::::::::           | EMAIL: ztucke@ztuc.cn
 *                 ..:::::::::::'           | DATETIME: 2020/01/31
 *             '::::::::::::'
 *                .::::::::::
 *           '::::::::::::::..
 *                ..::::::::::::.
 *              ``::::::::::::::::
 *               ::::``:::::::::'        .:::.
 *              ::::'   ':::::'       .::::::::.
 *            .::::'      ::::     .:::::::'::::.
 *           .:::'       :::::  .:::::::::' ':::::.
 *          .::'        :::::.:::::::::'      ':::::.
 *         .::'         ::::::::::::::'         ``::::.
 *     ...:::           ::::::::::::'              ``::.
 *   ```` ':.          ':::::::::'                  ::::..
 *                      '.:::::'                    ':'````..
 * +----------------------------------------------------------------------
 */
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2020/3/10
 * Time: 20:36
 */

namespace app\lnadmin\controller;
use app\core\InitController;
use app\common\Common;
// 引入SMTP服务器
use sendMail\SendMail;
use think\facade\Cache;
use think\facade\View;
use think\facade\Session;
use think\facade\Cookie;
use think\facade\Db;
use think\facade\App;
use think\facade\Config;
use think\facade\Request;
use app\lnadmin\model\admin\Signin;
use app\lnadmin\model\admin\AuthGroup;
use app\lnadmin\model\Base;
use app\lnadmin\model\admin\User;
use app\lnadmin\model\admin\ArticleLog;
use app\lnadmin\model\admin\Lnadmin as LnadminModel;
use app\lnadmin\model\admin\Article;
use app\lnadmin\model\admin\Image;
use app\lnadmin\model\admin\AuthGroupAccess;
use app\lnadmin\model\admin\Ems;
use app\lnadmin\model\admin\System;
use app\lnadmin\model\admin\AdminLog;
use app\lnadmin\model\admin\UserLog;
use app\lnadmin\model\admin\UserToken;

 /* 登录use app\lnadmin\model\Base;
 * Class Login
 * @package app\lnadmin\controller\admin
 */
class Lnadmin extends InitController
{
    protected function _initialize()
    {
        parent::_initialize();
    }
    // 列表
    public function list()
    {
        return View::fetch('lnadmin');
    }
       //列表详情
    public function index_json($limit='15')
    {
        $admin = new LnadminModel();
        $data = $admin->order('id asc')->paginate($limit);
         if (!empty($data)){
            // 获取图片
            foreach ($data as $k=>$v){
                 if (!empty($v['id'])){
                    $name = AuthGroup::findName($v['group_id']);
                $data[$k]['group_name'] = $name['group_name']??'未分配权限';
                $data[$k]['image'] = Image::image($v['id'],Upload::TYPE_ADMIN); 
                 }
             }
         }
        $this->result($data);
    }
   //// 获取左侧主菜单
   public function index()
    {   
        if ($this->request->isPost()) {
            return json(Base::getMenus($this->admin->id));
        }
        return View::fetch('lnadmin/index', [
            'image' => Image::image($this->admin->id,Upload::TYPE_ADMIN),
        ]);
    }
    // 默认首页
    public function home($limit='15')
    {
     //日统计
     $list = Signin::order(['id'=>'desc'])->paginate($limit); 
        // 获取用户信息
     
        if (!empty($list)) {
            $day=[
                'msg'=>'操作成功',
                'signNum' => Signin::whereTime('create_time', 'today')->where(['status' => 1])->count(),
                'code' => 200,
                'allNum' => User::inlineIp()
            ];
            foreach ($list as $k => $v) {
                if ($v['user_id']){
                    $day['signList'][]=[
                        'number'=>$v['user_id'],
                        'avatar'=>Image::image($v['user_id'], Upload::TYPE_USER),//会员头像
                        'name'=>User::findUser($v['user_id'])['username']??'已删除',
                        'time'=>$v['create_time'],
                        'types'=>$v['types']=='normal' ? '签到' : '补签' 
                    ];
                }
            }
            $datajson_day=json_encode($day);
        }
              //周统计
              
             foreach( $this->get_week() as $v) {  
                $week['data'][]=[     
                    'msg' => '操作成功',
                    'code' => 200,
                    'date' => $v,
                    'signNum' => Signin::whereDay('create_time', $v)->where(['status' => 1])->count()??0,
                    'unSignNum' => User::inlineIp()-(Signin::whereDay('create_time', $v)->where(['status' => 1])->count())??0,
                ];

            }
            $datajson_week=json_encode($week);
              //月统计
             
             foreach( self::get_day() as $v)     {
                $month['data'][]=[     
                    'msg'=>'操作成功',
                    'code'=>200,
                    'date'      => $v,
                    'signNum'   => Signin::whereDay('create_time', $v)->where(['status' => 1])->count()??0,
                    'unSignNum' => User::inlineIp()-(Signin::whereDay('create_time', $v)->where(['status' => 1])->count())??0,
                ];

            }
            $datajson_month=json_encode($month);   
        View::assign([
            'datajson_day'  => $datajson_day,
            'datajson_week' => $datajson_week,
            'datajson_month'=> $datajson_month,
            'count'         => User::comment('查询应签到人数')->count(),
            'signin'        => Signin::whereTime('create_time', 'today')->comment('查询今天签到人数')->count(),
            'view'          => ArticleLog::where(['status' => 1])->comment('浏览日志')->count(),
            'cat'           => Article::where(['status' => 1])->comment('文章数量')->count(),
            'config'        => self::configUrl(),
            'indexTips'     => self::getIndexTips($this->admin->id),
            'admin_log'     => AdminLog::comment('管理员日志')->count(),
            'user_log'      => UserLog::comment('会员日志')->count(),
            'expire_time'   => UserToken::where(['admin_id' => $this->admin->id])->value('expire_time'),
            'yesterday'     => ArticleLog::where(['status' => 1])->whereDay('create_time', 'yesterday')
                               ->comment('浏览日志')->count(),
        ]);
        
        return View::fetch('home');
    } 
    public static function configUrl()
        {
            // 系统信息
            $mysqlVersion = Db::query('SELECT VERSION() AS version');//VERSION() AS version  VERSION()重命名version

          $config       = [
            'document_root'       => $_SERVER['DOCUMENT_ROOT'],
            'server_os'           => php_uname(),
            'server_port'         => $_SERVER['SERVER_PORT'],
            'server_ip'           => GetHostByName(getHostName()) ?? '无法获取',
            'Public_ip'           => gethostbyname($_SERVER['SERVER_NAME']) ?? '无法获取',
            'server_soft'         => $_SERVER['SERVER_SOFTWARE'],
            'php_version'         => PHP_VERSION,
            'mysql_version'       => $mysqlVersion[0]['version'],
            'max_upload_size'     => ini_get('upload_max_filesize'),
            'version'             => App::version(),
            'max_execution_time'  => ini_get('max_execution_time'),
            'remaining_space'     => round((@disk_free_space(".") / (1024 * 1024)), 2) . 'M', //剩余空间
            'memory_limit'        => ini_get('memory_limit'), //最大占用内存
            'beijing_time'        => gmdate("Y年n月j日 H:i:s", time() + 8 * 3600), //北京时间
            'time'                => date("Y年n月j日 H:i:s"), //服务器时间
             ];
          return $config;
        }
  //每周时间
    function get_week($time = '', $format='Y-m-d'){
        $weekday = date($format, strtotime('this week'));
        $date = [];
        for ($i=0; $i<7; $i++){
            $date[$i]=date($format,strtotime($weekday)+$i*86400);
        }
        return $date;

    }
    //每月时间
    public static function get_day($time = '', $format='Y-m-d'){
        $time = $time != '' ? $time : time();
        $days = date('t', $time);
        $sday = strtotime(date('Y-m-01'));
        $date = [];
        for ($i=0; $i<date('d'); $i++){
            $date[$i] = date($format ,$sday+$i*86400);
        }
        return $date;

    }
    // 检查提示信息
   public static function getIndexTips($id)
{
       $password = LnadminModel::where('id', $id)->find();
       $weakPasswordArr = [
        'Aa563201',   
        'Aa123456', 
        'Aa12345678', 
        'Aa123456789',   
        'Aa654321', 
        'Aa111111', 
        'Aa000000', 
        'Aapassword',   
        'Aa56320178', 
        'Aaabc123', 
        '1qaz2wsx',
        'Aa111222',   
        'Aa333222', 
        'Aa222333', 
        'Aa111333',   
        'Aa888999', 
        'Aa222222', 
        'Aa333333', 
        'Aa555555',   
        'Aa666666', 
        'Aa888888', 
        'Aa999999'
    ];
       $isWeakPassword   =   false;
       foreach  ($weakPasswordArr  as  $weakPassword)  {
           $md5Password   =   md5($weakPassword  .   $password['salt']);
           if  ($password['password']   ===   $md5Password)  {
                 $isWeakPassword   =    true;
                 break;
           }
       }
       if   ($isWeakPassword)   {
             return '<h6 class="mb-0"><i class="layui-icon layui-icon-tips"></i> 提醒：密码太简单，请尽快修改后台初始密码！</h6>';
       }
       return   '';
}

    /**
     * 控制台
     * @return string
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     * @author: MK
     * @Time: 2020/4/5 21:46
     */
  
       // 后台登录跳转等待时间界面
    public function authentication()
    {
        if ($this->request->isPost()) {
        $param = $this->request->param();
            $check = LnadminModel::where(['email' => $param['email']])->find();
            if(!$check) return $this->error(__('Mailbox does not exist, please re-enter'));
        $list = System::where('key','config_sina_mail')->find()['jdata'];
        $data = Ems::where(['email' => $param['email']])->whereTime('create_time', 'today')
            ->group('email')->field(['email', 'MAX(times) AS times'])->findOrEmpty();
        if ($data->times >= 3) return $this->error(__('please try again tomorrow'));

        $exptime = time() + 60 * 10;//过期时间为十分钟
        
        $code = rand_number();//生成6位纯数字随机验证码
         
        $subject = __('Authentication');// 邮件标题
        $sendData = SendMail::sendEmail($param['email'],$list,$code,$subject);
        if($sendData){

        $newData = [
            'event' => __('Administrator authentication'),
            'times' => $data->times + 1,
            'email' => $param['email'],
            'code' => $code,
            'exptime' => $exptime,
            'ip' => $this->request->ip(),
        ];
        Ems::create($newData);
         return $this->success(true, 0, "$sendData", 1);
        
        }else{
            
       return $this->error("$sendData");
          }
        }
        return View::fetch('authentication');
    }

    // 身份验证
    public function authenticationCheck()
    {
        if ($this->request->isPost()) {
        $post = $this->request->post();
       if(strlen($post['code']) != 6) return $this->error('证码长度不正确');//字母全部转换成小写
        $model = Ems::where(['email' => $post['email'], 'code' => $post['code']])->find();
        if(!$model) return $this->error(__('Verification code error'));
        if ($model['exptime'] < time()) return $this->error(__('The verification code has expired'));
                 //验证码
                try{
                    $this->validate($post, ['captcha|验证码输入错误请手动点击刷新后重试！'=>'require|captcha']);
           
                }catch (\Exception $e){
                    $this->error($e->getMessage());
            }
        $check = LnadminModel::where(['email' => $post['email']])->find();
        $check->save();
         // 保持会话
        $map = ['admin_id' => $check->id, 'token' => $check->token, 'verification_time' => time(), 'expire_time'=>time()+60*60*24*7];   // 30天 
         $list = UserToken::where(['admin_id' => $check->id])->findOrEmpty();
         if($list['admin_id'] == $check->id){
            $check->save(['loginip' => $this->request->ip(), 'login_time' => time(), 'prev_time' => $check->login_time]);
            $list->save(['expire_time' => time()+60*60*24*7, 'verification_time'=>time()]);
            }else{
            $check->save(['loginip' => $this->request->ip(), 'login_time' => time(), 'prev_time' => $check->login_time]); 
            UserToken::create($map);
            } 
          // 保存状态
                $keep = [
                    'admin_id' => $check->id,
                    'username' => $check->username,
                ];
        session('admin_auth', $keep);
         // 设置token
        Session::set('token', $check->token);
       add_admin_log('authenticationCheck', '系统身份');// 记录后台行为日志;
        return $this->success('', 0, __('Verification successful, logging in'), url('lnadmin/index'));
       }
    }
    // 登录检查
    public function login()
    {
        if ($this->request->isPost()) {
            
        $param = $this->request->param();
         //验证规则
            $verify = input('_verify', true);
            if($verify!='0'){
                try{
         //是否验证码
            if(seo('adminyzm')=='1'){
          //验证规则
                    $this->validate($param, ['captcha|验证码输入错误请手动点击验证码刷新后重试！'=>'require|captcha']);
            }
                    $this->validate($param, 'login');
                }catch (\Exception $e){
                    $this->error($e->getMessage());
                }
            }
         $check = LnadminModel::check($param['username']);
        
         if(empty($check)) return $this->error('帐号不存在！请联系管理员');
        
         // $uid = AuthGroupAccess::findAccess($check->id);
        if (empty($check->AuthGroupAccess->uid) || $check->group_id == 5){
           return $this->error(__('Role not assigned').__('Illegal operation, please leave'));
        }
        if ($check->status <> 1) return $this->error(__('The account number is abnormal'));
        // 效验密码
        if ($check->password !== md5($param['password'] . $check->salt)) {
            // 记一次登录失败次数
            $check->loginfailure = $check->loginfailure + 1;
            $check->save();
            return $this->error(__('Login password error'));
        }
            $check->save(['loginip' => $this->request->ip(), 'login_time' => time(), 'prev_time' => $check->login_time]);
            $list = UserToken::where(['admin_id' => $check->id])->findOrEmpty();
           if($list->expire_time <= time()){
        return $this->success('', 0, '请验证身份',url('lnadmin/authentication?email='.base64_encode($check->email)));
           }
      // 保持会话
        $check->save();    
        // 保存状态
                $keep = [
                    'admin_id' => $check->id,
                    'username' => $check->username,
                ];
         session('admin_auth', $keep);
        // 设置token
        Session::set('token', $check->token);
         add_admin_log('login');// 记录后台行为日志
        return $this->success('', 0, __('Verification successful, logging in'), url('lnadmin/index'));
    }
        return View::fetch('login');
    }
    
    // 退出登录
    public function logout()
    {
        cookie('token',null);
        Session::delete('token'); 
       add_admin_log('logout');// 记录后台行为日志
       return $this->success('', '', __('Exit successful'));
    }

    // 新增
    public function add()
    {
        if ($this->request->isPost()) {
        $post = $this->request->post();
             if ((int)$post['group_id'] == 1) return $this->error(__('No additional administrator'));      
             //验证规则
            $verify = input('_verify', true);
            if($verify!='0'){
                try{
                    $this->validate($post, 'adminPwd');
                }catch (\Exception $e){
                    $this->error($e->getMessage());
                }
            }
        $add = $this->request->post();
        $res = LnadminModel::add($add);
       add_admin_log('add', '数据');// 记录后台行为日志;
        return $res ? $this->saveSuccess() : $this->error();
    }
     return $this->fetch('savelnadmin', ['group' => AuthGroup::groupName()]);
    }
 
    // 新增
    public function profile()
    {
        if ($this->request->isPost()) {
        $post = $this->request->post();
             if ((int)$post['group_id'] == 1) return $this->error(__('No additional administrator'));      
             //验证规则
            $verify = input('_verify', true);
            if($verify!='0'){
                try{
                    $this->validate($post, 'adminPwd');
                }catch (\Exception $e){
                    $this->error($e->getMessage());
                }
            }
        $add = $this->request->post();
        $res = LnadminModel::add($add);
       add_admin_log('add', '数据');// 记录后台行为日志;
        return $res ? $this->saveSuccess() : $this->error();
    }
     return $this->fetch('profile', ['config' => self::configUrl()]);
    }
 
    // 删除
    public function del()
    {
        if ($this->request->isPost()) {
        $param = $this->request->param();
        $uid = $this->request->get('uid');
        if ((int)$uid !== 1) return $this->success(true, 0, __('No right to delete'));
        AuthGroupAccess::del($param['id']);
        $result = LnadminModel::destroy($param['id']);
         if ($result == true) {
       add_admin_log('del', '数据');// 记录后台行为日志
                return $this->success('', '', '删除成功');
            }
        }
   
}
  // 编辑
    public function edit()
    {
        if ($this->request->isPost()) {
            // 获取部分变量
            $param = Request::param();
                 //验证规则
            $verify = input('_verify', true);
            if($verify!='0'){
                try{
                    $this->validate($param, 'adminPwd');
                }catch (\Exception $e){
                    $this->error($e->getMessage());
                }
            }
                        // 密码不填则是原始密码
            if (!empty($param['password'])) {
                $param['salt'] = Common::pwdMd5($param['password'])['salt'];
                $param['password'] = Common::pwdMd5($param['password'])['password'];
            }else{
                unset($param['password']);//删除密码
            }

            $data = LnadminModel::where('id', $param['id'])->find();
            if(!empty($param['username'])){
             if ($data['id'] == 1 && (int)$param['group_id'] !== 1) return $this->error('不可降权');
             if ($data['id'] !== 1 && (int)$param['group_id'] == 1) return $this->error('权限选择错误');
              //权限大于自己
             if ((int)$data['group_id'] < (int)$param['group'] && (int)$data['group_id'] !== 0)
            {
                if ((int)$param['group_id'] <= (int)$param['group']) return $this->error('无权操作');
                     
                    } 
               //   权限等于自己  
              if ($data['group_id'] == (int)$param['group'])
                    {

                 if ((int)$param['group_id'] !== (int)$param['group']) return $this->error('权限选择错误');
                     
                    }
                        // 写入权限组
            if (!empty($param['group_id'])){

               User::update(['group_id' => $param['group_id']], ['username' => $param['username']]);
               AuthGroupAccess::add($param['group_id'],$param['id']);
            }else{
               AuthGroupAccess::del($param['id']);
               User::update(['group_id' => $param['group_id']], ['username' => $param['username']]);
            }
                }
           $edit = LnadminModel::edit($param);
           add_admin_log('edit', '管理员数据');// 记录后台行为日志
        return $edit ? $this->saveSuccess() : $this->error();
    }
     return $this->fetch('savelnadmin', [
        'img' => Image::where(['table_id' => input('id'), 'types' => Upload::TYPE_ADMIN])->find(), 
        'group' => AuthGroup::groupName(), 
        'data' => LnadminModel::group(input('id'))
      ]);
    }
   // 清除模板，日志缓存
    public function clearTempLog()
    {
        $path = ROOT_PATH() . 'runtime' . DIRECTORY_SEPARATOR . 'cache' . DIRECTORY_SEPARATOR;
                //清空文件夹函数和清空文件夹后删除空文件夹函数的处理
                function deldir($path){
                //如果是目录则继续
                  if(is_dir($path)){
                //扫描一个文件夹内的所有文件夹和文件并返回数组
                  $p = scandir($path);
                  foreach($p as $val){
                //排除目录中的.和..
                 if($val !="." && $val !=".."){
                //如果是目录则递归子目录，继续操作
                 if(is_dir($path.$val)){
                //子目录中操作删除文件夹和文件
                  deldir($path.$val.'/');
                //目录清空后删除空文件夹
                 @rmdir($path.$val.'/');
                   }else{
                //如果是文件直接删除
                  unlink($path.$val);
                           }
                         }
                      }
                   }
                }
        //调用函数，传入路径deldir($path);
        try {
            $type = $this->request->request("type");
            switch ($type) {
                case 'all':
                case 'data':
                    deldir($path);
                    array_map( 'unlink', glob( root_path().'runtime'. DIRECTORY_SEPARATOR . 'log' . DIRECTORY_SEPARATOR . '*.log' ) );
                    array_map( 'unlink', glob( root_path().'runtime'. DIRECTORY_SEPARATOR . 'lnadmin' . DIRECTORY_SEPARATOR . 'temp' . DIRECTORY_SEPARATOR . '*.php' ) );
                    array_map( 'unlink', glob( root_path().'runtime'. DIRECTORY_SEPARATOR . 'store' . DIRECTORY_SEPARATOR . 'temp' . DIRECTORY_SEPARATOR . '*.php' ) );
                    Cache::clear();
                    if ($type == 'data') {
                        break;
                    }

            }
        } catch (\Exception $e) {
            $this->error($e->getMessage());
        }
        $this->success('', '', '清理缓存');
    }
    
     //缓存更新
    public function cache()
    {
        try {
            $type = $this->request->request("type");
            switch ($type) {
                case 'all':
                case 'data':
                    \util\File::del_dir(ROOT_PATH() . 'runtime' . DIRECTORY_SEPARATOR . 'cache');
                    Cache::clear();
                    if ($type == 'data') {
                        break;
                    }

                case 'template':
                    \util\File::del_dir(ROOT_PATH() . 'runtime' . DIRECTORY_SEPARATOR . 'temp');
                    if ($type == 'template') {
                        break;
                    }
                case 'addons':
                    // 插件缓存
                    Service::refresh();
                    if ($type == 'addons') {
                        break;
                    }
            }
        } catch (\Exception $e) {
            $this->error($e->getMessage());
        }
        $this->success('清理缓存');
    }
//修改密码
    public function editPassword()
    {
        if ($this->request->isPost()) {
            $param = $this->request->param();
            // 验证条件
            $verify = input('_verify', true);
            if($verify!='0'){
                try{
                    $this->validate($param, 'changePwd');
                }catch (\Exception $e){
                    $this->error($e->getMessage());
                }
            }
            $model = LnadminModel::where('id', $this->request->get('id'))->find();

             if ($model['password'] !== md5($param['password'] . $model['salt'])) {
            
            return $this->error('旧密码错误');
        }

            $param['password'] = Common::pwdMd5($param['new_password'])['password'];
          
            $param['salt'] = Common::pwdMd5($param['new_password'])['salt'];    //密码盐
          
            $result = LnadminModel::update($param, ['id'=>$this->request->get('id')]);
                
            if ($result == true) {
        add_admin_log('editPassword', '初始密码');// 记录后台行为日志
                $this->success('', '', '更新成功', url('lnadmin/index'));
            } else {
                $this->error($this->errorMsg);
            }
        }
        return $this->fetch('editpassword');
    }

}